package com.hntxk.cqzd.common.action;

import com.hntxk.core.framework.action.BaseController;
import com.hntxk.core.framework.model.BaseModel;
import com.hntxk.core.framework.model.ResponseModel;
import com.hntxk.core.framework.model.ResultModel;
import com.hntxk.core.framework.service.IBaseService;
import com.hntxk.core.util.JsonUtil;
import com.hntxk.core.util.StringUtil;
import com.hntxk.sp.util.OperActionEnum;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;

import javax.annotation.Nullable;
import javax.servlet.http.HttpServletRequest;
import javax.validation.constraints.NotNull;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author a
 * @Description: 模块公共controller<br>
 */
public class CqzdBaseController extends BaseController {

    /**日志记录工具*/
    private Logger logger;

    private IBaseService service;

    @Autowired
    protected HttpServletRequest request;

    public CqzdBaseController( @Nullable IBaseService service, @Nullable Logger logger) {
        super();
        this.service = service;
        this.logger = logger;
    }


    protected String delete() {
        return delete(request);
    }

    protected String delete(HttpServletRequest request) {
        return delete(request.getParameter("ids"),request);
    }

    protected String delete(String ids){
        return delete(ids,request);
    }

    protected String delete(String ids,HttpServletRequest request){
        String errMsg = service.delete(ids, getOperInfo("CQZD", request));
       return response(errMsg);
    }

    protected String save(BaseModel model){

        return save(model, request);
    }
    @SuppressWarnings("unchecked")
    protected String save(BaseModel model,HttpServletRequest request){
        ResultModel resultModel;
        if (OperActionEnum.Add.equalsActionID(model.getAction())) {

            resultModel = service.insert(model);

        }else{
            resultModel = service.update(model);
        }
        return getResultInfo(resultModel);
    }

    /**
     * 将list转换成JSON字符串 格式：{status:1,msg:null,data:[list]}
     * @param list List对象
     * @return JSONString
     */
    @Override
    protected String toJson(@NotNull List<?> list) {
        return toJson(list,"1",null);
    }

    /**
     * 将list转换成JSON字符串 格式： {status:'-1',msg:'保存失败',data:[list]}
     * @param list List对象
     * @param status @in(-1,1)
     * @param msg @in("保存失败","保存成功")
     * @return JSONString
     */
    protected String toJson(@NotNull List<?> list,@NotNull String status,String msg){

        Map<String,Object> map  = toJson(status,msg);
        map.put("data", list);
        return JsonUtil.obj2String(map);
    }

    /**
     * 将list转换成JSON字符串 格式： {status:'-1',msg:'保存失败'}
     * @param status @in(-1,1)
     * @param msg @in("保存失败","保存成功")
     * @return JSONString
     */
    protected Map<String,Object> toJson(@NotNull String status,String msg){
        Map<String,Object> data = new HashMap<>(8);
        data.put("status",status);
        data.put("msg",msg);
        return data;
    }

    @Override
    protected String getResultInfo(String errMsg) {
        return toJson("-1",errMsg).toString();
    }

    @Override
    protected String getResultInfo(ResultModel<?> model) {

        Map<String,Object> data = JsonUtil.obj2Map(model);
        if (model.hasError()){
            data.put("status","-1");
            data.put("msg",model.getErrMsg());
        }else {
            data.put("status","1");
            data.put("msg",null);
        }
        return JsonUtil.obj2String(data);
    }

    @Override
    protected String toJson(@NotNull List<?> list, String dataName) {
        return this.toJson(list);
    }

    @Override
    protected String toJson(Object data, String dataName) {
        return this.toJson(data);
    }


    /**
     * 将data转换成JSON字符串  {status:'1',msg:null,data:{}}
     * @param data 任意对象
     * @return JSONString
     */
    @Override
    protected String toJson(@NotNull Object data) {
        return toJson(data, "1",null);
    }

    /**
     * 将data转换成JSON字符串  {status:'-1',msg:'保存失败',data:{}}
     * @param data 任意对象
     * @return JSONString
     */
    protected String toJson(@NotNull Object data,@NotNull String status,String msg) {
        Map<String,Object> map = toJson(status,msg);
        map.put("data",data);
        return JsonUtil.obj2String(map);
    }


    protected String toJson(@NotNull BaseModel model, @NotNull ResponseModel responseModel) {

        if (!responseModel.containsKey("status")){
            responseModel.put("status","1");
        }
        if (!responseModel.containsKey("msg")){
            responseModel.put("msg",null);
        }
        if (!responseModel.containsKey("page")){
            responseModel.put("page", model.getPagination().getPageIndex()+1);
        }

        return responseModel.toJson();
    }

    protected String response(String msg){

        Map<String,Object> map = toJson(StringUtils.isEmpty(msg)?"1":"-1",msg);
        return JsonUtil.obj2String(map);
    }

    protected String responseOk(){
        return response(null);
    }

    protected String responseSorry(@NotNull String msg){
       return response(msg);
    }

    public Logger getLogger() {
        return logger;
    }



    @org.jetbrains.annotations.NotNull
    protected ResponseEntity<byte[]> getResponseEntity(byte[] bytes, String fileName, String contentType) {
        try {
            //获得浏览器信息并转换为大写
            String agent = request.getHeader("User-Agent").toUpperCase();
            //IE浏览器和Edge浏览器，名称乱码
            if (agent.indexOf("MSIE") > 0 || (agent.indexOf("GECKO")>0 && agent.indexOf("RV:11")>0)) {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            } else {  //其他浏览器
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }
        }catch (UnsupportedEncodingException e){
            logger.error("文件名转码异常，文件名：{}",fileName);
        }
        String contentDisposition = "attachment; fileName=" +  fileName;
        if (null != contentType){
            contentDisposition = "fileName=" +  fileName;
        }else {
            contentType = "application/octet-stream";
        }
        ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
                .header(HttpHeaders.CONTENT_TYPE, contentType)
                .header(HttpHeaders.CONTENT_LENGTH, bytes.length + "")
                .header("Connection", "close");
        return bodyBuilder.body(bytes);
    }
    /**
     * 生产下载或打开文件的 ResponseEntity
     *
     * @param isDownload  是否下载文件
     * @param fileName    文件名称
     * @param contentType 内容类型
     * @param fileBytes   文件内容
     * @return
     */
    @NotNull
    public ResponseEntity<Object> toResponseEntity(boolean isDownload, String fileName, String contentType, byte[] fileBytes) {
        try {
            if (StringUtil.isNull(fileName)){
                fileName = request.getParameter("fileName");
            }
            if (StringUtil.isNull(fileName)){
                fileName = request.getParameter("filename");
            }
            //获得浏览器信息并转换为大写
            String agent = request.getHeader("User-Agent").toUpperCase();
            //IE浏览器和Edge浏览器，名称乱码
            if (agent.indexOf("MSIE") > 0 || (agent.indexOf("GECKO") > 0 && agent.indexOf("RV:11") > 0)) {
                fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.name());
            } else {  //其他浏览器
                fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1);
            }
        } catch (UnsupportedEncodingException e) {
            logger.error("文件名转码异常，文件名：{}", fileName);
        }
        //文件内容类型
        String contentDisposition;
        if (isDownload) {
            contentType = "application/octet-stream";
            contentDisposition = "attachment; fileName=" + fileName;
        } else {
            contentDisposition = "fileName=" + fileName;
        }
        ResponseEntity.BodyBuilder bodyBuilder = ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, contentDisposition)
                .header(HttpHeaders.CONTENT_TYPE, contentType)
                .header(HttpHeaders.CONTENT_LENGTH, fileBytes.length + "")
                .header("Connection", "close");
        return bodyBuilder.body(fileBytes);
    }

}
